﻿namespace System.Windows
{
    public static class FrameworkElementExtension
    {
        public static bool HasWidth(this FrameworkElement element)
        {
            return
                element.Width != 0 &&
                double.IsNegativeInfinity(element.Width) == false &&
                double.IsPositiveInfinity(element.Width) == false;
        }

        public static bool HasHeight(this FrameworkElement element)
        {
            return
                element.Height != 0 &&
                double.IsNegativeInfinity(element.Height) == false &&
                double.IsPositiveInfinity(element.Height) == false;
        }

        public static bool HasActualWidth(this FrameworkElement element)
        {
            return
                element.ActualWidth != 0 &&
                double.IsNegativeInfinity(element.ActualWidth) == false &&
                double.IsPositiveInfinity(element.ActualWidth) == false;
        }

        public static bool HasActualHeight(this FrameworkElement element)
        {
            return
                element.ActualHeight != 0 &&
                double.IsNegativeInfinity(element.ActualHeight) == false &&
                double.IsPositiveInfinity(element.ActualHeight) == false;
        }

        //====================================================================================================
        //以上是判断界面元素是否存在高度及宽度
        //----------------------------------------------------------------------------------------------------
        //以下是获取界面元素尺寸
        //====================================================================================================

        public static bool TryGetSize(this FrameworkElement element, out Size size)
        {
            if (element.HasWidth() == false || element.HasHeight() == false)
            {
                size = Size.Empty;
                return false;
            }

            var width = element.Width;
            var height = element.Height;
            size = new Size(width, height);
            return true;
        }

        public static bool TryGetActualSize(this FrameworkElement element, out Size size)
        {
            if (element.HasActualWidth() == false || element.HasActualHeight() == false)
            {
                size = Size.Empty;
                return false;
            }

            var width = element.ActualWidth;
            var height = element.ActualHeight;
            size = new Size(width, height);
            return true;
        }

        //====================================================================================================
        //以上是获取界面元素尺寸
        //----------------------------------------------------------------------------------------------------
        //以下是获取界面元素区域
        //====================================================================================================

        public static bool TryGetBounds(this FrameworkElement element, Point location, out Rect bounds)
        {
            if (element.HasWidth() == false || element.HasHeight() == false)
            {
                bounds = new Rect();
                return false;
            }

            var width = element.Width;
            var height = element.Height;
            var size = new Size { Width = width, Height = height };
            bounds = new Rect { Location = location, Size = size };
            return true;
        }

        public static bool TryGetActualBounds(this FrameworkElement element, Point location, out Rect bounds)
        {
            if(element.HasActualWidth() == false || element.HasActualHeight() == false)
            {
                bounds = new Rect();
                return false;
            }

            var width = element.ActualWidth;
            var height = element.ActualHeight;
            var size = new Size { Width = width, Height = height };
            bounds = new Rect { Location = location, Size = size };
            return true;
        }

        public static bool TryGetCenter(this FrameworkElement element, Point location, out Point center)
        {
            Rect bounds;
            if(TryGetBounds(element, location , out bounds) == false)
            {
                center = new Point();
                return false;
            }
            center = bounds.GetCenter();
            return true;
        }

        public static bool TryGetActualCenter(this FrameworkElement element, Point location, out Point center)
        {
            Rect bounds;
            if (TryGetActualBounds(element, location, out bounds) == false)
            {
                center = new Point();
                return false;
            }
            center = bounds.GetCenter();
            return true;
        }
    }
}
